package org.example.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @description: MQ异常处理配置
 * @author: 谢超
 * @date: 2023/8/25 18:00
 */
@Configuration
@Slf4j
public class RabbitMQErrorConfig {

    /**
     * 错误交换机
     */
    private final String shortLinkErrorExchange = "short_link.error.exchange";

    /**
     * 异常队列
     */
    private final String shortLinkErrorQueue = "short_link.error.queue";

    /**
     * 异常routing.key
     */
    private final String shortLinkErrorRoutingKey = "short_link.error.routing.key";

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 声明异常交换机
     * @return
     */
    @Bean
    public TopicExchange errorTopicExchange() {
        return new TopicExchange(shortLinkErrorExchange, true, false);
    }

    /**
     * 声明异常队列
     * @return
     */
    @Bean
    public Queue errorQueue() {
        return new Queue(shortLinkErrorQueue, true);
    }

    /**
     * 建立队列和交换机的绑定关系
     * @return
     */
    @Bean
    public Binding bingingErrorQueueAndExchange() {
        return BindingBuilder.bind(errorQueue()).to(errorTopicExchange()).with(shortLinkErrorRoutingKey);
    }

    /**
     * 配置RepublishMessageRecoverer,消息消费重试一定次数后，用特定的routingKey转发到指定的交换机中，方便后续的排除和告警
     * @return
     */
    @Bean
    public MessageRecoverer messageRecoverer() {
        return new RepublishMessageRecoverer(rabbitTemplate, shortLinkErrorExchange, shortLinkErrorRoutingKey);
    }
}
